﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Net;
using BCCommon;
using BCDto.Common.SystemInformation;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.PlatformAbstractions;
using Newtonsoft.Json;
using System.Reflection;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Configuration;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace BCTMSRESTful.Controllers.Management.System.SystemInfo
{
    /// <summary>
    /// 系统信息控制器
    /// </summary>
    [ApiExplorerSettings(GroupName = "Admin-SystemTools")]
    [Route("api/v1/sim/[controller]")]
    public class SystemInfoController : ManagementBaseController
    {
        private readonly IConfiguration configuration;
        public SystemInfoController(IConfiguration configuration)
        {
            this.configuration = configuration;
        }

        #region 获取系统信息
        /// <summary>
        /// 获取系统信息。
        /// </summary>
        /// <response code="200">系统信息</response>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(SystemInformationDto), 200)]
        public IActionResult Get()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            AssemblyCompanyAttribute applicationCompanyName = (AssemblyCompanyAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyCompanyAttribute));
            AssemblyProductAttribute applicationProductName = (AssemblyProductAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyProductAttribute));

            ApplicationEnvironment appEnvironment = PlatformServices.Default.Application;
            SystemInformationDto systemInformationDto = new SystemInformationDto();

            systemInformationDto.ServerIP = string.Join("\r\n", this.GetServerIPAddress());
            systemInformationDto.ApplicationCompanyName = applicationCompanyName.Company;
            systemInformationDto.ApplicationName = applicationProductName.Product;
            systemInformationDto.ApplicationVersion = appEnvironment.ApplicationVersion;
            systemInformationDto.ApplicationBasePath = appEnvironment.ApplicationBasePath;
            systemInformationDto.ApplicationRuntime = appEnvironment.RuntimeFramework.FullName;
            systemInformationDto.Environment = this.GetEnvironmentInfo();
            systemInformationDto.OsVersion = Environment.OSVersion.VersionString;
            systemInformationDto.OperatingSystemBitType = Environment.Is64BitOperatingSystem ? "X64" : "X86";
            bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
            systemInformationDto.OsDescription = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? OSPlatform.Linux.ToString() : RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? OSPlatform.Windows.ToString() : OSPlatform.OSX.ToString();
            systemInformationDto.MachineName = Environment.MachineName;
            systemInformationDto.CurrentTime = DateTime.Now.ToString("yyyy-MM-dd");
            systemInformationDto.WebsiteDirectory = Path.Combine(new DirectoryInfo(Directory.GetCurrentDirectory()).Parent.FullName, configuration["WebsiteName"]);
            systemInformationDto.WebsiteHost = configuration["DefaultHost"];
            if (isWindows)
            {
                GetWindowsInformation(systemInformationDto);
            }
            else
            {
                GetLinuxInformation(systemInformationDto);
            }
            return this.Ok(systemInformationDto);
        }
        #endregion

        #region 查询相应服务器信息
        /// <summary>
        /// 获取服务器IP地址列表
        /// </summary>
        /// <returns></returns>
        private string[] GetServerIPAddress()
        {
            string hostName = Dns.GetHostName(); //获得主机名
            IPAddress[] addressList = Dns.GetHostAddresses(hostName); //获得 IP 列表
            List<string> list = new List<string>();
            foreach(var item in addressList)
            {
                Regex regex = new Regex("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
                if (regex.IsMatch(item.ToString()))
                {
                    list.Add(item.ToString());
                }
            }
            return list.ToArray();
        }
        /// <summary>
        /// 获取系统环境信息
        /// </summary>
        /// <returns></returns>
        private EnvironmentDto GetEnvironmentInfo()
        {
            return new EnvironmentDto
            {
                CommandLine = Environment.CommandLine,
                CurrentDirectory = Environment.CurrentDirectory,
                ExitCode = Environment.ExitCode,
                HasShutdownStarted = Environment.HasShutdownStarted,
                MachineName = Environment.MachineName,
                NewLine = Environment.NewLine,
                OSVersion = Environment.OSVersion.VersionString,
                ProcessorCount = Environment.ProcessorCount,
                SystemDirectory = Environment.SystemDirectory,
                TickCount = Environment.TickCount,
                UserDomainName = Environment.UserDomainName,
                UserInteractive = Environment.UserInteractive,
                UserName = Environment.UserName,
                Version = Environment.Version.ToString(),
                WorkingSet = Environment.WorkingSet
            };
        }

        /// <summary>
        /// 获取Windows系统信息
        /// </summary>
        /// <param name="systemInformationDto"></param>
        private void GetWindowsInformation(SystemInformationDto systemInformationDto)
        {




            //ExeCommandUtils cmd = new ExeCommandUtils();
            //string mysqlCmdResult = cmd.ExeCommand("systeminfo", true);
            //systemInformationDto.MysqlDirectory =
            //systemInformationDto.MysqlVersion =
            //systemInformationDto.NginxDirectory =
            //systemInformationDto.NginxVersion=
            //systemInformationDto.OpenSslDirectory=
            //systemInformationDto.SystemCpuUsage = 
            //systemInformationDto.SystemCpuFree =
            //systemInformationDto.SystemMemoryTotal = 
            //systemInformationDto.SystemMemoryFree = 
            //systemInformationDto.SystemMemoryUsed = 
        }

        /// <summary>
        /// 获取Linux系统信息
        /// </summary>
        /// <param name="systemInformationDto"></param>
        private void GetLinuxInformation(SystemInformationDto systemInformationDto)
        {
            ExeCommandUtils cmd = new ExeCommandUtils();
            string mysqlCmdResult = cmd.ExeCommand("whereis mysql", false);
            if (mysqlCmdResult.IndexOf(" ") > -1)
            {
                systemInformationDto.MysqlDirectory = mysqlCmdResult.Split(' ')[1];
                string mysqlVersion = cmd.ExeCommand("mysql -V", false);
                mysqlVersion = mysqlVersion.Substring(mysqlVersion.IndexOf("Distrib"));
                systemInformationDto.MysqlVersion = mysqlVersion.Substring(0, mysqlVersion.IndexOf(',')).Replace("Distrib", "");
            }
            string nginxCmdResult = cmd.ExeCommand("whereis nginx", false);
            if (nginxCmdResult.IndexOf(" ") > -1)
            {
                systemInformationDto.NginxDirectory = nginxCmdResult.Replace("nginx:", "").TrimStart(' ').Split(' ')[0];
                string nginxVersion = cmd.ExeCommand("nginx -v", false);
                string[] nginxInfo = nginxVersion.Split("\n");
                systemInformationDto.NginxVersion = nginxInfo[0].Replace("nginx version:", "");
            }
            string openSSLCmdResult = cmd.ExeCommand("whereis openssl", false);
            if (openSSLCmdResult.IndexOf(" ") > -1)
            {
                systemInformationDto.OpenSslDirectory = openSSLCmdResult.Split(' ')[1];
            }
            string systemCPUCmdResult = cmd.ExeCommand("top -bn 1 -i -c", false);
            string cpu = systemCPUCmdResult.Split("\n")[2].Replace("%Cpu(s):", "");
            systemInformationDto.SystemCpuUsage = cpu.Split(",").Single(p => p.Contains("us")).Replace("us", "").Trim();
            systemInformationDto.SystemCpuFree = cpu.Split(",").Single(p => p.Contains("id")).Replace("id", "").Trim();
            string memory = systemCPUCmdResult.Split("\n")[3];
            memory = memory.Substring(memory.IndexOf(":") + 1);
            double.TryParse(memory.Split(",").Single(p => p.Contains("total")).Replace("total", "").Trim(), out double systemMemoryTotal);
            double.TryParse(memory.Split(",").Single(p => p.Contains("free")).Replace("free", "").Trim(), out double systemMemoryFree);
            double.TryParse(memory.Split(",").Single(p => p.Contains("used")).Replace("used", "").Trim(), out double systemMemoryUsed);
            systemInformationDto.SystemMemoryTotal = Math.Round(systemMemoryTotal / 1024 / 1024, 2, MidpointRounding.AwayFromZero) + "G";
            systemInformationDto.SystemMemoryFree = Math.Round(systemMemoryFree / 1024 / 1024, 2, MidpointRounding.AwayFromZero) + "G";
            systemInformationDto.SystemMemoryUsed = Math.Round(systemMemoryUsed / 1024 / 1024, 2, MidpointRounding.AwayFromZero) + "G";
        }
        #endregion
    }
}
